﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Common;
using Common.Entities;
using System.Collections.ObjectModel;
using System.IO;

namespace WpfHardCodedStringsFinder.Views
{
	/// <summary>
	/// Interaction logic for DuplicateStringsWindow.xaml
	/// </summary>
	public partial class DuplicateStringsWindow : Window
	{
		public List<FailInfo> Fails { get; set; }
		public List<ProcessedFileInfo> ProcessedFiles { get; set; }

		public string RootNamespace { get; set; }

		public readonly string PropResourcesPath = "Properties.Resources";

		public List<DuplicateStringInfo> DuplicateStrings
		{
			get { return (List<DuplicateStringInfo>)GetValue(DuplicateStringsProperty); }
			set { SetValue(DuplicateStringsProperty, value); }
		}

		public static readonly DependencyProperty DuplicateStringsProperty =
			DependencyProperty.Register("DuplicateStrings", typeof(List<DuplicateStringInfo>), typeof(DuplicateStringsWindow), new PropertyMetadata(new List<DuplicateStringInfo>()));

		public DuplicateStringsWindow()
		{
			InitializeComponent();
			ProcessedFiles = new List<ProcessedFileInfo>();

			this.Loaded += new RoutedEventHandler(DuplicateStringsWindow_Loaded);
		}

		void DuplicateStringsWindow_Loaded(object sender, RoutedEventArgs e)
		{
			this.DataContext = this;
		}

		private void btnProcess_Click(object sender, RoutedEventArgs e)
		{
			int tmpCount = 0;

			DuplicateStrings.ForEach(item =>
				{
					DuplicateStrings[tmpCount].ResourceName = string.IsNullOrEmpty(RootNamespace) ? string.Format("{0}.{1}", PropResourcesPath, item.ResourceName) :
						string.Format("{0}.{1}.{2}", RootNamespace, PropResourcesPath, item.ResourceName);
					tmpCount++;
				});

			foreach (var item in DuplicateStrings)
			{
				foreach (KeyValuePair<string, int> pair in item.OccurrencesInFile.Where(x => x.Value > 0))
				{
					if (pair.Value > 0)
					{
						StringBuilder contentBuilder = null;
						List<int> indicies = new List<int>();
						using (StreamReader sr = new StreamReader(pair.Key))
						{
							contentBuilder = new StringBuilder(sr.ReadToEnd());
						}
						int index = -1;
						int offset = 0;
						while ((index = contentBuilder.IndexOf(item.ResourceString, offset, true)) != -1)
						{
							int sIndx, eIndx;
							sIndx = contentBuilder.LeftToken(index, '"');
							eIndx = contentBuilder.RightToken(index + item.ResourceString.Length, '"');

							contentBuilder.Remove(sIndx, (eIndx - sIndx) + 1);
							contentBuilder.Insert(sIndx, item.ResourceName);

							offset = sIndx + item.ResourceName.Length;
							indicies.Add(sIndx);
						}

						//Chaeck for file attributes 
						if ((System.IO.File.GetAttributes(pair.Key) & FileAttributes.ReadOnly) != 0)
						{
							try
							{
								System.IO.File.SetAttributes(pair.Key, FileAttributes.Normal);
							}
							catch (System.IO.IOException) { }
							catch (System.UnauthorizedAccessException) { }
						}

						//delete backup if it exist
						if (System.IO.File.Exists(System.IO.Path.ChangeExtension(pair.Key, ".backup")))
							System.IO.File.Delete(System.IO.Path.ChangeExtension(pair.Key, ".backup"));

						System.IO.File.Copy(pair.Key, System.IO.Path.ChangeExtension(pair.Key, ".backup"));

						StreamWriter sw = null;
						try
						{
							sw = new StreamWriter(pair.Key, false);
							sw.Write(contentBuilder.ToString());
							sw.Flush();

							ProcessedFiles.Add(new ProcessedFileInfo()
							{
								FileName = pair.Key,
								ResourceString = item.ResourceString,
								ResourceName = item.ResourceName,
								Indicies = indicies
							});
						}
						catch (Exception ex)
						{
							if (System.IO.File.Exists(pair.Key))
								System.IO.File.Delete(pair.Key);

							System.IO.File.Copy(System.IO.Path.ChangeExtension(pair.Key, ".backup"), pair.Key);
							System.IO.File.Delete(System.IO.Path.ChangeExtension(pair.Key, ".backup"));

							if (Fails == null)
								Fails = new List<FailInfo>();
							Fails.Add(new FailInfo()
							{
								FileName = pair.Key,
								FailReason = ex,
								ResourceString = item.ResourceString,
								ResourceVariable = item.ResourceName
							});
						}
						finally
						{
							if (sw != null) sw.Dispose();

							contentBuilder.Clear(); contentBuilder = null;
						}

					}
				}
			}

			if (Fails != null && Fails.Count > 0)
				MessageBox.Show(string.Format("Unprocessed file counts - > {0}", Fails.Count));

			MessageBox.Show(string.Format("Processed file counts - > {0}", ProcessedFiles.Count));
		}
	}
}
